package com.dupf.product.rpc.service.impl;

import com.dupf.common.annotation.BaseService;
import com.dupf.common.base.BaseServiceImpl;
import com.dupf.common.util.ItvJsonUtil;
import com.dupf.common.util.RedisUtil;
import com.dupf.product.dao.mapper.ProductSalePriceSettingMapper;
import com.dupf.product.dao.model.*;
import com.dupf.product.rpc.api.ProductExchangeRateService;
import com.dupf.product.rpc.api.ProductLogisticsPriceService;
import com.dupf.product.rpc.api.ProductLogisticsSettingService;
import com.dupf.product.rpc.api.ProductSalePriceSettingService;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * ProductSalePriceSettingService实现
 * Created by dupf on 2018/3/20.
 */
@Service
@Transactional
@BaseService
public class ProductSalePriceSettingServiceImpl extends BaseServiceImpl<ProductSalePriceSettingMapper, ProductSalePriceSetting, ProductSalePriceSettingExample> implements ProductSalePriceSettingService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProductSalePriceSettingServiceImpl.class);
    private static final int MINUTES_30 = 30 * 60;

    @Autowired
    ProductSalePriceSettingMapper productSalePriceSettingMapper;
    @Autowired
    ProductLogisticsSettingService logisticsSettingService;
    @Autowired
    ProductLogisticsPriceService logisticsPriceService;
    @Autowired
    ProductExchangeRateService exchangeRateService;

    @Override
    public Float calculateSalePrice(Integer orgId, Integer userId, String country, Float costPrice, Float weight) {
        if (costPrice == null || costPrice == 0) {
            return 0f;
        }

        ProductSalePriceSetting salePriceSetting;
        String key = "product-sale-price-setting:" + orgId + ":" + userId + ":" + weight;

        String redisStore = RedisUtil.get(key);
        if (StringUtils.isEmpty(redisStore)) {
            ProductSalePriceSettingExample salePriceSettingExample = new ProductSalePriceSettingExample();
            salePriceSettingExample.createCriteria().andOrgIdEqualTo(orgId).andUserIdEqualTo(userId);
            salePriceSetting = this.selectFirstByExample(salePriceSettingExample);
            if (salePriceSetting != null) {
                RedisUtil.set(key, JSONObject.fromObject(salePriceSetting).toString(), MINUTES_30);
            }
        } else {
            salePriceSetting = ItvJsonUtil.readValue(redisStore, ProductSalePriceSetting.class);
        }
        Float multipleRate = getMultipleRate(salePriceSetting, country);
        Float totalCostPrice = costPrice;

        if (weight != null && weight != 0) {

            Integer logisticsId = getLogisticsId(orgId, country, weight);

            if (logisticsId != null) {
                ProductLogisticsPrice logisticsPrice = getLogisticsPrice(orgId, logisticsId, weight);
                if (logisticsPrice != null) {
                    totalCostPrice += getLogisticsPriceByCountry(logisticsPrice, country);
                }
            }
        }


        return new BigDecimal(totalCostPrice).multiply(new BigDecimal(multipleRate)).divide(getExchangeRate(orgId, country), 2, BigDecimal.ROUND_UP).floatValue();
    }

    /**
     * 获取汇率
     *
     * @param orgId
     * @param country
     * @return
     */
    private BigDecimal getExchangeRate(Integer orgId, String country) {
        ProductExchangeRate exchangeRate = getProductExchangeRate(orgId);

        if (exchangeRate == null || StringUtils.isEmpty(country)) {
            return new BigDecimal(1);
        }

        BigDecimal exchangeRateAmount = new BigDecimal(1);

        switch (country.toUpperCase()) {
            case "CA":
                exchangeRateAmount = exchangeRate.getCad();
                break;
            case "IN":
                exchangeRateAmount = exchangeRate.getInr();
                break;
            case "MX":
                exchangeRateAmount = exchangeRate.getMxn();
                break;
            case "AT":
            case "DE":
            case "IT":
            case "BE":
            case "FR":
            case "NL":
            case "ES":
                exchangeRateAmount = exchangeRate.getEur();
                break;
            case "NO":
                exchangeRateAmount = exchangeRate.getNok();
                break;
            case "JP":
                exchangeRateAmount = exchangeRate.getJpy();
                break;
            case "AU":
                exchangeRateAmount = exchangeRate.getAud();
                break;
            case "US":
                exchangeRateAmount = exchangeRate.getUsd();
                break;
            case "UK":
                exchangeRateAmount = exchangeRate.getGbp();
                break;
            default:
                exchangeRateAmount = new BigDecimal(1);
        }


        return exchangeRateAmount;
    }

    private Float getLogisticsPriceByCountry(ProductLogisticsPrice logisticsPrice, String country) {
        if (logisticsPrice == null || StringUtils.isEmpty(country)) {
            return 0f;
        }

        Float logisticsPriceAmount = 0f;

        switch (country.toUpperCase()) {
            case "CA":
                logisticsPriceAmount = logisticsPrice.getPriceCa();
                break;
//            case "IN":
//                salePriceRate = salePriceSetting.getPriceIn();
//                break;
            case "MX":
                logisticsPriceAmount = logisticsPrice.getPriceMx();
                break;
//            case "AT":
//                salePriceRate = salePriceSetting.getPriceAt();
//                break;
            case "DE":
                logisticsPriceAmount = logisticsPrice.getPriceDe();
                break;
            case "IT":
                logisticsPriceAmount = logisticsPrice.getPriceIt();
                break;
//            case "NO":
//                salePriceRate = salePriceSetting.getPriceNo;
//                break;
            case "JP":
                logisticsPriceAmount = logisticsPrice.getPriceJp();
                break;
//            case "BE":
//                salePriceRate = salePriceSetting.getPriceBe();
//                break;
            case "FR":
                logisticsPriceAmount = logisticsPrice.getPriceFr();
                break;
//            case "AU":
//                salePriceRate = salePriceSetting.getPriceAu();
//                break;
            case "US":
                logisticsPriceAmount = logisticsPrice.getPriceUs();
                break;
            case "UK":
                logisticsPriceAmount = logisticsPrice.getPriceUk();
                break;
//            case "NL":
//                salePriceRate = salePriceSetting.getPriceNl;
//                break;
            case "ES":
                logisticsPriceAmount = logisticsPrice.getPriceEs();
                break;
            default:
                logisticsPriceAmount = 0f;
        }

        return logisticsPriceAmount;
    }

    /**
     * 获取汇率
     *
     * @param orgId
     * @return
     */
    private ProductExchangeRate getProductExchangeRate(Integer orgId) {
        String key = "product-exchange-rate" + orgId;

        String redisStore = RedisUtil.get(key);
        if (StringUtils.isEmpty(redisStore)) {
            ProductExchangeRateExample example = new ProductExchangeRateExample();
            example.createCriteria().andOrgIdEqualTo(orgId);
            ProductExchangeRate exchangeRate = exchangeRateService.selectFirstByExample(example);

            if (exchangeRate != null) {
                RedisUtil.set(key, JSONObject.fromObject(exchangeRate).toString(), MINUTES_30);
            }
            return exchangeRate;
        } else {
            return ItvJsonUtil.readValue(redisStore, ProductExchangeRate.class);
        }
    }

    /**
     * 获取物流价格
     *
     * @param orgId
     * @param logisticsId
     * @param weight
     * @return
     */
    private ProductLogisticsPrice getLogisticsPrice(Integer orgId, Integer logisticsId, Float weight) {
        String key = "product-logistics-price:" + orgId + ":" + logisticsId + ":" + weight;

        String redisStore = RedisUtil.get(key);
        if (StringUtils.isEmpty(redisStore)) {
            ProductLogisticsPriceExample example = new ProductLogisticsPriceExample();
            example.createCriteria().andOrgIdEqualTo(orgId).andLogisticsIdEqualTo(logisticsId).andWeightGreaterThanOrEqualTo(weight);
            example.setOrderByClause("weight asc");
            ProductLogisticsPrice logisticsPrice = logisticsPriceService.selectFirstByExample(example);
            if (logisticsPrice != null) {
                RedisUtil.set(key, JSONObject.fromObject(logisticsPrice).toString(), MINUTES_30);
            }
            return logisticsPrice;
        } else {
            return ItvJsonUtil.readValue(redisStore, ProductLogisticsPrice.class);
        }
    }

    /**
     * 获取设置的物流ID
     *
     * @param orgId
     * @param country
     * @param weight
     * @return
     */
    private Integer getLogisticsId(Integer orgId, String country, Float weight) {
        ProductLogisticsSetting logisticsSetting;
        String key = "product-logistics-id:" + orgId + ":" + country + ":" + weight;

        String redisStore = RedisUtil.get(key);
        if (StringUtils.isEmpty(redisStore)) {
            ProductLogisticsSettingExample example = new ProductLogisticsSettingExample();
            example.createCriteria().andOrgIdEqualTo(orgId).andLweightLessThan(weight).andHweightGreaterThanOrEqualTo(weight);

            logisticsSetting = logisticsSettingService.selectFirstByExample(example);
            if (logisticsSetting != null) {
                RedisUtil.set(key, JSONObject.fromObject(logisticsSetting).toString(), MINUTES_30);
            }
        } else {
            logisticsSetting = ItvJsonUtil.readValue(redisStore, ProductLogisticsSetting.class);
        }

        return logisticsSetting == null ? null : getLogisticsIdByCountry(logisticsSetting, country);
    }

    /**
     * 获取设置的倍数
     *
     * @param salePriceSetting
     * @param country
     * @return
     */
    private Float getMultipleRate(ProductSalePriceSetting salePriceSetting, String country) {

        if (salePriceSetting == null || StringUtils.isEmpty(country)) {
            return 1f;
        }

        Float salePriceRate = 1f;

        switch (country.toUpperCase()) {
            case "CA":
                salePriceRate = salePriceSetting.getPriceCa();
                break;
//            case "IN":
//                salePriceRate = salePriceSetting.getPriceIn();
//                break;
            case "MX":
                salePriceRate = salePriceSetting.getPriceMx();
                break;
//            case "AT":
//                salePriceRate = salePriceSetting.getPriceAt();
//                break;
            case "DE":
                salePriceRate = salePriceSetting.getPriceDe();
                break;
            case "IT":
                salePriceRate = salePriceSetting.getPriceIt();
                break;
//            case "NO":
//                salePriceRate = salePriceSetting.getPriceNo;
//                break;
            case "JP":
                salePriceRate = salePriceSetting.getPriceJp();
                break;
//            case "BE":
//                salePriceRate = salePriceSetting.getPriceBe();
//                break;
            case "FR":
                salePriceRate = salePriceSetting.getPriceFr();
                break;
//            case "AU":
//                salePriceRate = salePriceSetting.getPriceAu();
//                break;
            case "US":
                salePriceRate = salePriceSetting.getPriceUs();
                break;
            case "UK":
                salePriceRate = salePriceSetting.getPriceUk();
                break;
//            case "NL":
//                salePriceRate = salePriceSetting.getPriceNl;
//                break;
            case "ES":
                salePriceRate = salePriceSetting.getPriceEs();
                break;
            default:
                salePriceRate = 1f;
        }

        return salePriceRate;

    }

    /**
     * 获取物流id
     *
     * @param logisticsSetting
     * @param country
     * @return
     */
    private Integer getLogisticsIdByCountry(ProductLogisticsSetting logisticsSetting, String country) {

        if (logisticsSetting == null || StringUtils.isEmpty(country)) {
            return null;
        }

        Integer logisticsId = null;

        switch (country.toUpperCase()) {
            case "CA":
                logisticsId = logisticsSetting.getLogisticsCa();
                break;
//            case "IN":
//                salePriceRate = salePriceSetting.getPriceIn();
//                break;
            case "MX":
                logisticsId = logisticsSetting.getLogisticsMx();
                break;
//            case "AT":
//                salePriceRate = salePriceSetting.getPriceAt();
//                break;
            case "DE":
                logisticsId = logisticsSetting.getLogisticsDe();
                break;
            case "IT":
                logisticsId = logisticsSetting.getLogisticsIt();
                break;
//            case "NO":
//                salePriceRate = salePriceSetting.getPriceNo;
//                break;
            case "JP":
                logisticsId = logisticsSetting.getLogisticsJp();
                break;
//            case "BE":
//                salePriceRate = salePriceSetting.getPriceBe();
//                break;
            case "FR":
                logisticsId = logisticsSetting.getLogisticsFr();
                break;
//            case "AU":
//                salePriceRate = salePriceSetting.getPriceAu();
//                break;
            case "US":
                logisticsId = logisticsSetting.getLogisticsUs();
                break;
            case "UK":
                logisticsId = logisticsSetting.getLogisticsUk();
                break;
//            case "NL":
//                salePriceRate = salePriceSetting.getPriceNl;
//                break;
            case "ES":
                logisticsId = logisticsSetting.getLogisticsEs();
                break;
            default:
                logisticsId = null;


        }

        return logisticsId;

    }
}